package org.wangzhen.spring.event.springdemo;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.ContextStartedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;

/**
 * 演示Spring注解EventListener的用法（如何去监听或者）
 * 1、方法参数如果使用ApplicationEvent这个父类，那么可以接受所有的spring事件，因为ApplicationEvent是spring中所有事件的父类
 * 2、方法参数如果指定的是ApplicationEvent的子类，那么只能处理相应子类的事件，例如只处理（ContextRefreshedEvent/ContextStartedEvent），
 *      那么只有在刷新或者启动的时候才能处理相应的事件；
 * 3、如果事件要通过异步的方式来执行，需要开启@EnableAsync ，然后在方法上使用@Async注解就可以了
 * 4、可以使用@Order注解的方式来控制所有@EventListener方法的执行顺序，数字越小，优先级越高
 */
public class EventListenerAnnotationDemo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

        context.register(EventListenerAnnotationDemo.class);

        context.refresh();

        context.start();

        context.close();
    }

    /**
     * 方式一：
     * 使用ApplicationEvent用来监听所有的spring事件
     * @param applicationEvent
     */
    @EventListener
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        System.out.println("onApplicationEvent=="+ applicationEvent);
    }

    /**
     * 方式二：
     * 标注了EventListener注解的方法参数：使用具体类型的事件类，例如：刷新/启动/关闭
     * 使用Order注解用来演示同一事件，order值越小优先执行
     * @param applicationEvent
     */
    @Order(2)
    @EventListener
    public void onApplicationEventOrder1(ContextRefreshedEvent applicationEvent) {
        System.out.println("order1 = " +applicationEvent);
    }

    /**
     * 方式二：
     * 标注了EventListener注解的方法参数：使用具体类型的事件类，例如：刷新/启动/关闭
     * 使用Order注解用来演示同一事件，order值越小优先执行
     * @param applicationEvent
     */
    @Order(1)
    @EventListener
    public void onApplicationEventOrder2(ContextRefreshedEvent applicationEvent) {
        System.out.println("order2 = "+applicationEvent);
    }

    /**
     * 方式二：
     * 标注了EventListener注解的方法参数：使用具体类型的事件类，例如：刷新/启动/关闭
     * @param applicationEvent
     */
    @EventListener
    public void onApplicationEvent(ContextStartedEvent applicationEvent) {
        System.out.println(applicationEvent);
    }

    /**
     * 方式二：
     * 标注了EventListener注解的方法参数：使用具体类型的事件类，例如：刷新/启动/关闭
     * @param applicationEvent
     */
    @EventListener
    public void onApplicationEvent(ContextClosedEvent applicationEvent) {
        System.out.println(applicationEvent);
    }

}
